﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SchoolManagerMVC.BusinessAbstract.Interfaces;
using SchoolManagerMVC.Web.Areas.Administration.Controllers;
using SchoolManagerMVC.BusinessConcrete.DTO;
using System.Web.Mvc;
using SchoolManagerMVC.Web.Models;

namespace SchoolManagerMVC.Tests.Controllers.AdminArea
{
    [TestClass]
    public class MembershipControllerTest
    {
        public Mock<IRepository> _repoMock;
        public Mock<IInitializeBD> _initDB;
        MembershipController controller;

        [TestInitialize]
        public void setup()
        {           
            _repoMock = new Mock<IRepository>();            
            _initDB = new Mock<IInitializeBD>();
            _initDB.Setup(x => x.createDB("")).Returns(true);
            _initDB.Setup(x => x.AddMembershipToDB()).Returns(true);
            _initDB.Setup(x => x.createTables("")).Returns(true);
            _initDB.Setup(x => x.createKeys("")).Returns(true);
            _initDB.Setup(x => x.createRoles()).Returns(true);
            _initDB.Setup(x => x.addAdminAccount()).Returns(true);
            _initDB.Setup(x => x.addSampleAccounts(It.IsAny<IRepository>())).Returns(true);
            _initDB.Setup(x => x.addSampleData()).Returns(true);
            _initDB.Setup(x => x.disableDbCreation()).Returns(true);

            controller = new MembershipController(_repoMock.Object, _initDB.Object);
        }

        [TestMethod]
        public void IndexReturnsCreateView()
        {
            
            var result = controller.Index() as ViewResult;
            Assert.AreEqual("CreateAspMembership", result.ViewName);
        }

        [TestMethod]
        public void CreateGetReturnsCreateView()
        {
            var result = controller.CreateAspMembership() as ViewResult;
            Assert.AreEqual("CreateAspMembership", result.ViewName);
        }

        //test if InitDB has run if adminDTO.LoadTestData is true.

        [TestMethod]
        public void adminDTO_AcceptMemebershipCreation_True_Runs_InitDB()
        {
            AdminCreationDTO adminDTO = new AdminCreationDTO()
            {
                AcceptMemebershipCreation = true,
                LoadTestData = false
            };

            var result = controller.CreateAspMembership(adminDTO) as ViewResult;
            Assert.AreEqual("Success", result.ViewName);
            _initDB.Verify(x => x.createDB(""), Times.Once(), "CreateDB was not ran");
            _initDB.Verify(x => x.AddMembershipToDB(), Times.Once(), "AddMembershipToDB was not ran");
            _initDB.Verify(x => x.createTables(""), Times.Once(), "createTables was not ran");
            _initDB.Verify(x => x.createKeys(""), Times.Once(), "createKeys was not ran");
            _initDB.Verify(x => x.createRoles(), Times.Once(), "createRoles was not ran");
            _initDB.Verify(x => x.addAdminAccount(), Times.Once(), "addAdminAccount was not ran");
            _initDB.Verify(x => x.disableDbCreation(), Times.Once(), "disableDbCreation was not ran");            
        }

        [TestMethod]
        public void adminDTO_AcceptMemebershipCreation_False_Returns_CreateMemebershipView()
        {
            AdminCreationDTO adminDTO = new AdminCreationDTO()
            {
                AcceptMemebershipCreation = false,
                LoadTestData = false
            };

            var result = controller.CreateAspMembership(adminDTO) as ViewResult;
            Assert.AreEqual("CreateAspMembership", result.ViewName);
        }

        [TestMethod]
        public void adminDTO_LoadTestData_True_Runs_Sample_Data()
        {
            AdminCreationDTO adminDTO = new AdminCreationDTO()
            {
                AcceptMemebershipCreation = true,
                LoadTestData = true
            };

            var result = controller.CreateAspMembership(adminDTO) as ViewResult;
            Assert.AreEqual("Success", result.ViewName);
            _initDB.Verify(x => x.addSampleAccounts(It.IsAny<IRepository>()), Times.Once(), "addSampleAccounts was not ran");
            _initDB.Verify(x => x.addSampleData(), Times.Once(), "addSampleData was not ran");            
        }

        [TestMethod]
        public void adminDTO_LoadTestData_False_Skips_Sample_Data()
        {
            AdminCreationDTO adminDTO = new AdminCreationDTO()
            {
                AcceptMemebershipCreation = true,
                LoadTestData = false
            };

            var result = controller.CreateAspMembership(adminDTO) as ViewResult;
            Assert.AreEqual("Success", result.ViewName);
            _initDB.Verify(x => x.addSampleAccounts(It.IsAny<IRepository>()), Times.Never(), "addSampleAccounts was not ran");
            _initDB.Verify(x => x.addSampleData(), Times.Never(), "addSampleData was not ran");
        }
    }
}
